﻿using Mapster;
using SqlSugar;
using Zhp.Common.Exception;
using Zhp.Common.Helper;
using Zhp.Entity.Design;
using Zhp.IService.Design;
using Zhp.Model.Design;
using Zhp.Service.Base;
using Zhp.SqlSugar.Repository;

namespace Zhp.Service.Design
{
    public class DesignFormService : BaseService<DesignForm>, IDesignFormService
    {
        private IDesignTableService _designTableService;
        public DesignFormService(
            IBaseRepository<DesignForm> rep,
            IDesignTableService designTableService) 
        { 
            _rep = rep;
            _designTableService = designTableService;
        }
        public async Task<List<DesignFormModel>> Query(DesignFormQuery p)
        {
            var emailList = await _rep.GetPageListAsync(new List<IConditionalModel>
            {

            }, p, x => x.CreateTime, OrderByType.Desc);

            return emailList.Adapt<List<DesignFormModel>>();
        }


        public async Task<bool> Create(DesignFormEdit p)
        {
            if (await _rep.IsAnyAsync(x => x.Name == p.Name))
            {
                throw new AlertException($"名称：{p.Name}已存在!");
            }
            var entity = p.Adapt<DesignForm>();
            return await _rep.InsertAsync(entity);
        }

        public async Task<bool> Update(DesignFormEdit p)
        {
            if (await _rep.CountAsync(x => x.Id != p.Id && x.Name == p.Name) > 0)
            {
                throw new AlertException($"名称：{p.Name}已存在!");
            }
            var entity = await _rep.GetByIdAsync(p.Id);
            if (entity != null)
            {
                p.Adapt(entity);
                return await _rep.UpdateAsync(entity);
            }
            return false;
        }

        public async Task<bool> Delete(long id)
        {
            return await _rep.DeleteByIdAsync(id);
        }

        public async Task<DesignFormEdit> Details(long id)
        {
            var entity = await _rep.GetByIdAsync(id);

            return entity.Adapt<DesignFormEdit>();
        }

        public async Task<List<DesignFormSelect>> Select()
        {
            var result = new List<DesignFormSelect>();

            var list = await _rep.AsQueryable().Select(x => new { x.Id, x.Name }).ToListAsync();

            foreach (var item in list)
            {
                result.Add(new DesignFormSelect
                {
                    FormId = item.Id,
                    FormName = item.Name
                });
            }

            return result;
        }

        public async Task<List<DesignFormFieldSelect>> QueryFieldSelect(long formId)
        {
            var result = new List<DesignFormFieldSelect>();
            var form = await _rep.GetByIdAsync(formId);

            var formFieldList = await GetFormField(form.FormItemList);

            if (!string.IsNullOrEmpty(form.SourceCode))
            {
                var columns = await _designTableService.QueryColumn(form.SourceCode);
                foreach (var item in columns)
                {
                    var obj = new DesignFormFieldSelect
                    {
                        FieldName = item.ColumnName,
                        FieldText = item.ColumnDescription,
                    };
                    var formField = formFieldList.FirstOrDefault(x => x.Field == item.ColumnName);
                    if (formField != null)
                    {
                        obj.FieldType = formField.FieldType;
                        obj.Options = formField.Options;
                    }
                    result.Add(obj);
                }
            }
            
            return result;
        }

        public async Task<List<DesignFormField>> QueryFormFieldConfig(long formId)
        {
            var form = await _rep.GetByIdAsync(formId);
            if (form != null)
            {
                return new List<DesignFormField>();
            }
            else
            {
                return await GetFormField(form.FormItemList);
            }
        }

        public async Task<List<DesignFormField>> GetFormField(string formItemList)
        {
            var result = new List<DesignFormField>();

            var itemList = formItemList.ToObject<List<DesignFormItem>>();

            ExtractField(result, itemList);

            return await Task.FromResult(result);
        }

        private void ExtractField(List<DesignFormField> result, List<DesignFormItem> itemList)
        {
            foreach (var item in itemList)
            {
                if (item.Group == "form")
                {
                    result.Add(new DesignFormField
                    {
                        Field = item.Field,
                        DataType = item.DataType,
                        FieldType = item.Type,
                        Options = item.Options
                    });
                }
                else
                {
                    if (item.FormItemList != null)
                    {
                        ExtractField(result, item.FormItemList);
                    }
                }
            }
        }
    }
}
